using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Dapper;
using hao_Common.Dapper.Db;
using hao_Common.Dapper.Query; // 确保使用正确的命名空间

namespace hao_Common.Dapper.Repository
{
    /// <summary>
    /// 仓储扩展方法，提供表达式树查询功能
    /// </summary>
    public static class RepositoryExtensions
    {
        /// <summary>
        /// 创建查询构建器
        /// </summary>
        public static IQueryBuilder<T> CreateBuilder<T>(this IGenericRepository<T> repository, Expression<Func<T, bool>> predicate = null) where T : class, ISoftDelete
        {
            var builder = new ExpressionQueryBuilder<T>();
            if (predicate != null)
            {
                builder.Where(predicate);
            }
            // 自动添加未删除条件
            builder.Where(e => !e.IsDeleted);
            return builder;
        }
        
        /// <summary>
        /// 使用表达式树构建器执行查询
        /// </summary>
        public static async Task<IEnumerable<T>> QueryWithBuilder<T>(this IGenericRepository<T> repository, 
            Func<hao_Common.Dapper.Query.IQueryBuilder<T>, hao_Common.Dapper.Query.IQueryBuilder<T>> builderAction) where T : class, ISoftDelete
        {
            // 获取连接工厂
            var connectionFactory = GetConnectionFactory(repository);
            using var conn = connectionFactory.CreateConnection();
            
            // 创建并配置查询构建器
            var builder = new hao_Common.Dapper.Query.ExpressionQueryBuilder<T>();
            builder = (hao_Common.Dapper.Query.ExpressionQueryBuilder<T>)builderAction(builder);
            
            // 自动添加未删除条件
            builder.Where(e => !e.IsDeleted);
            
            // 执行查询
            return await conn.QueryAsync<T>(builder.GetQuery(), builder.Param);
        }
        
        /// <summary>
        /// 使用表达式树构建器执行分页查询
        /// </summary>
        public static async Task<(IEnumerable<T> Items, int TotalCount)> QueryPagedWithBuilder<T>(this IGenericRepository<T> repository,
            Func<hao_Common.Dapper.Query.IQueryBuilder<T>, hao_Common.Dapper.Query.IQueryBuilder<T>> builderAction,
            int pageNumber,
            int pageSize) where T : class, ISoftDelete
        {
            // 获取连接工厂
            var connectionFactory = GetConnectionFactory(repository);
            using var conn = connectionFactory.CreateConnection();
            
            // 创建并配置查询构建器
            var builder = new hao_Common.Dapper.Query.ExpressionQueryBuilder<T>();
            builder = (hao_Common.Dapper.Query.ExpressionQueryBuilder<T>)builderAction(builder);
            
            // 自动添加未删除条件
            builder.Where(e => !e.IsDeleted);
            
            // 查询总数
            var countBuilder = new hao_Common.Dapper.Query.ExpressionQueryBuilder<T>();
            countBuilder = (hao_Common.Dapper.Query.ExpressionQueryBuilder<T>)builderAction(countBuilder);
            countBuilder.Where(e => !e.IsDeleted);
            int totalCount = await conn.QuerySingleAsync<int>(countBuilder.GetCountQuery(), countBuilder.Param);
            
            // 应用分页
            string dataSql = $"{builder.GetQuery()} LIMIT {pageSize} OFFSET {(pageNumber - 1) * pageSize}";
            var items = await conn.QueryAsync<T>(dataSql, builder.Param);
            
            return (items, totalCount);
        }
        
        /// <summary>
        /// 获取连接工厂
        /// </summary>
        private static IDbConnectionFactory GetConnectionFactory<T>(IGenericRepository<T> repository) where T : class, ISoftDelete
        {
            // 通过反射获取DapperGenericRepository中的连接工厂
            var field = repository.GetType().GetField("_connectionFactory", 
                System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                
            if (field == null)
            {
                // 尝试获取QueryableRepository中的连接工厂
                if (repository is QueryableRepository<T> queryableRepo)
                {
                    return queryableRepo.GetConnectionFactory();
                }
                
                throw new InvalidOperationException("无法获取连接工厂，请确保仓储实现是DapperGenericRepository或QueryableRepository");
            }
            
            return field.GetValue(repository) as IDbConnectionFactory;
        }
    }
}